package de.fhffm.gaertnerei.gui;
/**
 * @author Michael Wyrzykowski & Julian Schmücker
 */

import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.regex.Pattern;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.Query;
import javax.swing.JButton;
import javax.swing.JFormattedTextField;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.text.MaskFormatter;

import de.fhffm.gaertnerei.exceptions.EingabeException;
import de.fhffm.gaertnerei.tabellen.Aussaat;
import de.fhffm.gaertnerei.tabellen.Bewaesserung;

public class BewaesserungFenster implements ActionListener{

	private Double bewaesserungsMenge = 0.0;
	
	private String bewaesserungsMengeString = null;
	private String datumString = null;
	private String vorherigesDatumString = null;
	private String aussaatDatumString = null;
	
	private JTextField textfeldBewaesserungsMenge = new JTextField(8);
	
	private JFormattedTextField textfeldDatum ;
	
	private JLabel labelBewaesserungsMenge = new JLabel(" Liter :");
	private JLabel labelDatum	= new JLabel(" Datum :");
	private JLabel labelInfo = new JLabel();
	
	private JButton buttonSpeichern = new JButton("Speichern");
	private JButton buttonAbbrechen = new JButton("Abbrechen");
	
	private JPanel panelEingabe = new JPanel(new GridLayout(3,2));
	private JPanel panelButton = new JPanel();
	private JPanel panelInfo = new JPanel();
	
	private JFrame bewaesserungsFrame = new JFrame();
	
	private List<String> ausgewaehlteZeile;
	
	private StringBuilder stringBuilder = new StringBuilder();
	
	private MaskFormatter datumFormat= null;
	
	private SimpleDateFormat simpleDateFormat = new SimpleDateFormat("dd.MM.yyyy");
	
	private Date aktuellesDatum = new Date();
	private Date aussaatDatum;
	private Date eingegebenesDatum ;
	
	private int bewaesserungID;
	
	private boolean bewaesserungVorhanden = false;
	
	private Bewaesserung bewaesserung = new Bewaesserung();
	
	public BewaesserungFenster(List<String> ausgewaehlteZeile){
		
		this.ausgewaehlteZeile = ausgewaehlteZeile;
		
		erstelleFenster();
		setzeInfo();
		setzeEingaben();
		setzeButton();
		setzePanel();
	}
	
	@Override
	public void actionPerformed(ActionEvent e) {
		
		Object obj = e.getSource();
		
		if (obj == buttonAbbrechen) {	
			bewaesserungsFrame.dispose();
		}
		
		/*
		 * Eingabe wird überprüft wenn alles OK ist
		 * dan wird überprüft ob die Bewässerung neu hinzugefügt oder 
		 * geupdatet werden muss.
		 * Falls die Bewässerung geupdatet werden soll wird geprüft ob nicht schon
		 * eine Bewässerung an dem gleichen Tag stattgefunden hat.
		 * Wenn dies nicht der Fall ist kann geupdatet werden, 
		 * Beim Updaten wird nochmal überprüft ob das Update
		 * nicht evtl abgebrochen wurde, weil der nutzer darauf hingewiesen
		 * wurde das die vorherige Bewässerung gelöscht wird und er das nicht möchte.
		 */

			if(obj == buttonSpeichern){

				if(ueberpruefeEingabe()) {
				
					if(bewaesserungVorhanden){
						
						if(istUpdateMoeglich()){
						
							if(doUpdateBewaesserung()){
								einfügenEnde();
							}else{
								//Update abebrochen -> nix passiert
							}
						}else{
							System.out.println("Datum Fehler!");
						}
						
					}else{
					fuegeBewaesserungEin();
					einfügenEnde();
					}

					
				}else{
					System.out.println("Ein Fehler ist aufgetreten");
				}
			}
	}

	private void erstelleFenster() {

		bewaesserungsFrame.setSize(400,500);
		bewaesserungsFrame.setLocationRelativeTo(null);
		bewaesserungsFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
		bewaesserungsFrame.setVisible(true);
		bewaesserungsFrame.setResizable(false);
		bewaesserungsFrame.setLayout(new BorderLayout());
		bewaesserungsFrame.setTitle("Bewässerung festlegen");
	}

	private void setzeInfo() {

		stringBuilder.append("<html>Bewässerung für die Pflanze: '").append(ausgewaehlteZeile.get(2)).append("'");
		stringBuilder.append("<br>").append("Aus der Aussaat mit der ID: ").append(ausgewaehlteZeile.get(0)).append(" festlegen.<br><br>");
		
		ueberpruefeBewaesserung();
		stringBuilder.append("<br></html>");

		labelInfo.setText(stringBuilder.toString());
		panelInfo.add(labelInfo);
		stringBuilder.setLength(0);		
	}

	private void setzeEingaben() {

		panelEingabe.add(labelBewaesserungsMenge);
		panelEingabe.add(textfeldBewaesserungsMenge);
		textfeldBewaesserungsMenge.setToolTipText("Menge des gegossenen Wassers in Liter");
		panelEingabe.add(labelDatum);
		setzeDatumAlsText();		
	}

	private void setzeButton() {

		panelButton.add(buttonSpeichern);
		panelButton.add(buttonAbbrechen);
		buttonSpeichern.addActionListener(this);
		buttonAbbrechen.addActionListener(this);
	}

	private void setzePanel() {

		bewaesserungsFrame.getContentPane().add(panelInfo, BorderLayout.NORTH);
		bewaesserungsFrame.getContentPane().add(panelEingabe,BorderLayout.CENTER);
		bewaesserungsFrame.getContentPane().add(panelButton,BorderLayout.SOUTH);
		bewaesserungsFrame.pack();		
	}

	private void ueberpruefeBewaesserung() {
		
		if(istBewaesserungVorhanden()){
			stringBuilder.append("Für diese Aussaat gibt es eine").append("<br>vorheriges Bewässerung vom ").
			append(bewaesserung.getDatum()).append("<br>");
			vorherigesDatumString = bewaesserung.getDatum();
			
		}else {
			System.out.println("Noch keine Bewaesserung vorhanden");
		}
		
	}

	private boolean istBewaesserungVorhanden() {
		
		int aussaatID = Integer.parseInt(ausgewaehlteZeile.get(0));

		EntityManagerFactory factory;
		factory = Persistence.createEntityManagerFactory("chilidatenbank");
		EntityManager em = factory.createEntityManager();
		em.getTransaction().begin();
		
		Query q = em.createQuery("SELECT a FROM Aussaat a WHERE a.aussaatID =:ID");
				  q.setParameter("ID",aussaatID);
		Aussaat aussaat = (Aussaat) q.getSingleResult();	
		
		Bewaesserung bewaesserung = aussaat.getBewaesserung();
		em.close();
		try{	
			 /*Wenn es keinen vorherige Bewässerung für die Aussaat gibt wird hier eine Exception geworfen
			  * wenn dies geschieht wird die Exception gefangen und man weiß das es noch keine Bewässerung gibt
			  */
			bewaesserungID = bewaesserung.getBewaesserungID();
			}catch(NullPointerException e){
				bewaesserungVorhanden = false;
				return false;
			}
			
			 this.bewaesserung = bewaesserung;
			 bewaesserungVorhanden = true;
			return true;
	}

	private void setzeDatumAlsText() {
		
		try {
			datumFormat = new MaskFormatter("##.##.####");
		} catch (ParseException e) {
			e.printStackTrace();
		}
		
		textfeldDatum = new JFormattedTextField(datumFormat);
		textfeldDatum.setText(simpleDateFormat.format(aktuellesDatum));
		panelEingabe.add(textfeldDatum);
	}

	private boolean doUpdateBewaesserung() {		
		
		Object[] options = {"Überschreiben","Abbrechen"};
		int selected = JOptionPane.showOptionDialog(null,"Die vorherige Bewässerung wird überschrieben!", "ACHTUNG!", JOptionPane.YES_NO_OPTION,
			   JOptionPane.WARNING_MESSAGE, null , options ,options[1]);
		switch(selected){
			case 0:

				System.out.println("Die aktuelle Bewässerung wird überschrieben");
				EntityManagerFactory factory;
				factory = Persistence.createEntityManagerFactory("chilidatenbank");
				EntityManager em = factory.createEntityManager();
				em.getTransaction().begin();
	
				Query q = em.createQuery("UPDATE Bewaesserung b SET b.bewaesserungsMenge =:menge, b.datum =:datum WHERE b.bewaesserungID =:ID");
							q.setParameter("menge", bewaesserungsMengeString);
							q.setParameter("datum", datumString);
							q.setParameter("ID",bewaesserungID);
							q.executeUpdate();
			  
				em.getTransaction().commit();
				em.close(); 
				return true;
	
			case 1:
				System.out.println("Update abgebrochen!");
				return false;
	
		}
		return false;
	}

	private boolean istUpdateMoeglich() {
		
		try{
			vergleicheDatum();
		}catch(EingabeException e){
			return false;
		}
		return true;
	}

	private void vergleicheDatum() throws EingabeException {
		
		String aktuellesDatumString = simpleDateFormat.format(aktuellesDatum);
		
		if(vorherigesDatumString.equals(aktuellesDatumString)){
			throw new EingabeException("Eine Pflanze kann nur einmal pro Tag bewässert werden!");
		}
		
	}

	private void einfügenEnde() {
		
		Object[] options = {"Fertig!","Neue Bewässerung!"};
		int selected = JOptionPane.showOptionDialog(null,"Bewässerung hinzugefügt!", "Hinzufügen Erfolgreich", JOptionPane.YES_NO_OPTION,
					   JOptionPane.QUESTION_MESSAGE, null , options ,options[1]);
		
		switch(selected){
		case 0:
			bewaesserungsFrame.dispose();
			break;
		case 1:
			bewaesserungsFrame.dispose();
			new FortschrittTabellenFenster(2);
			break;
		}
	}

	private void fuegeBewaesserungEin() {
		
		int aussaatID = Integer.parseInt(ausgewaehlteZeile.get(0));
		EntityManagerFactory factory;
		factory = Persistence.createEntityManagerFactory("chilidatenbank");
		EntityManager em = factory.createEntityManager();
		em.getTransaction().begin();
		
		Query q = em.createQuery("SELECT a FROM Aussaat a WHERE a.aussaatID =:ID");
				  q.setParameter("ID",aussaatID);
		Aussaat aussaat = (Aussaat) q.getSingleResult();	
		
		Bewaesserung bewaesserung = new Bewaesserung();
		
		bewaesserung.setAussaat(aussaat);
		bewaesserung.setBewaesserungsMenge(bewaesserungsMengeString);
		bewaesserung.setDatum(datumString);
		
		em.persist(aussaat);
		em.persist(bewaesserung);
		em.getTransaction().commit();
		em.refresh(aussaat);
		em.refresh(bewaesserung);
		em.close();
		
	}

	private boolean ueberpruefeEingabe() {
		
		boolean pruefe = false;
		try {
			ueberpruefeDatum();
			pruefe = hohleEingabe();


		} catch (EingabeException e) {
			System.out.println("Eingabe Fehler");
		} catch (NumberFormatException n){
			System.out.println("Bitte Zahlen eingeben!");
			JOptionPane.showMessageDialog(null,"Bitte für die Menge nur Zahlen eingeben.","Fehler",JOptionPane.ERROR_MESSAGE);
		}
		return pruefe;
	}
	
	private void ueberpruefeDatum() throws EingabeException {
		
		hohleAussaatDatum();
		datumString = textfeldDatum.getText();
		
		if(istDatumVerwendbar()){
			
			/*Das Aktuelle Datum wird in einen String mit dem format dd.mm.yyyy umgewandelt.
			Dan wird das aktuelle Datum wieder als Date gespeichert nur mit dem vorher definierten format
			so kann das aktuelle Datum mit dem eingegebenen Datum verglichen werden */
							
			String aktuellesDatumString = simpleDateFormat.format(aktuellesDatum);
			String[] teilString = datumString.split(Pattern.quote(".")); // Das eingegebene Datum wird gesplittet
			 
			try {
				 aktuellesDatum = simpleDateFormat.parse(aktuellesDatumString);
				
			} catch (ParseException e) {
				e.printStackTrace();
			}
			
			if(eingegebenesDatum.after(aktuellesDatum)){
				throw new EingabeException("Das eingegebene Datum darf nicht nach dem aktuellem Datum liegen!");
				
			// Eingegebenes Datum ist ungültig wenn kein Tag, Monat oder Jahr angegeben wird bsp.: 00.00.0000	
			// um dies zu überprüfen wird der vorher gesplittete String genutzt
			}else if((teilString[0]).equals("00") || (teilString[1].equals("00") || teilString[2].equals("0000") || teilString[2].substring(0, 1).equals("0")) ){
			    throw new EingabeException("Das Datum muss im format tt.mm.yyyy eingegeben werden und darf nicht 0 sein");
			
			}else if(eingegebenesDatum.equals(aktuellesDatum)){
				System.out.println("Alles ok");
			}
			
		}else {
			throw new EingabeException("Das Datum der Bewässerung darf nicht vor dem Aussaat Datum liegen!");
		}
	}
		
	private boolean istDatumVerwendbar() {
			
			try {
				
				aussaatDatum = simpleDateFormat.parse(aussaatDatumString);
				eingegebenesDatum = simpleDateFormat.parse(datumString);
			} catch (ParseException e) {
				
				e.printStackTrace();
				return false;
			}

			if(eingegebenesDatum.before(aussaatDatum)){
				
				return false;
			}
			return true;
		}

	private void hohleAussaatDatum() {
			
		int aussaatID = Integer.parseInt(ausgewaehlteZeile.get(0));
		EntityManagerFactory factory;
		factory = Persistence.createEntityManagerFactory("chilidatenbank");
		EntityManager em = factory.createEntityManager();
		em.getTransaction().begin();
			
		Query q = em.createQuery("SELECT a FROM Aussaat a WHERE a.aussaatID =:ID");
				  q.setParameter("ID",aussaatID);
				  
		Aussaat aussaat = (Aussaat) q.getSingleResult();	
		aussaatDatumString = aussaat.getAussaatDatum();
			
		em.close();
	}

	private boolean hohleEingabe() throws EingabeException,NumberFormatException {
			
		bewaesserungsMenge = Double.parseDouble(textfeldBewaesserungsMenge.getText());
		stringBuilder.append(bewaesserungsMenge).append(" Liter");
		bewaesserungsMengeString = stringBuilder.toString();
		stringBuilder.setLength(0);

		if(isEingabeLeer()){
				
			throw new EingabeException("Eine oder mehrere Eingaben fehlen, bitte keine Negativen Zahlen angeben!");
			
		}else{

			return true;
		}
	}

	private boolean isEingabeLeer() {
			
		if(bewaesserungsMenge <= 0.0  ){
				
			return true;
			
		}else{
			
			return false;
		}
	}
}